package com.sike.netty.im.server.handler;

import com.sike.netty.im.common.command.Message;
import com.sike.netty.im.common.command.MessageBuilder;
import com.sike.netty.im.common.command.OneChatRequestCommand;
import com.sike.netty.im.common.command.OneChatResponseCommand;
import com.sike.netty.im.common.enums.Attributes;
import com.sike.netty.im.common.enums.CommandTypeEnum;
import com.sike.netty.im.common.enums.ResponseStatusEnum;
import com.sike.netty.im.server.service.BeanFactory;
import com.sike.netty.im.server.service.SessionService;
import com.sike.netty.im.server.service.UserInfoCache;
import com.sike.netty.im.server.service.UserInfoDTO;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.AttributeKey;

import java.util.Optional;

/**
 * 单聊功能请求
 *
 * @author chenssy
 * @date 2023/09/16
 */
public class OneChatRequestHandler extends SimpleChannelInboundHandler<OneChatRequestCommand> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, OneChatRequestCommand msg) throws Exception {
        SessionService sessionService = (SessionService) BeanFactory.getServiceBean(SessionService.class);
        // 1. 获取目标用户的 Channel
        UserInfoDTO toUserInfo = UserInfoCache.getUserInfoByUserName(msg.getToUserName());
        Channel toUserChannel = Optional.ofNullable(sessionService.getChannelByUserId(toUserInfo.getUserId()))
                .orElseThrow(()-> new RuntimeException(msg.getToUserName() + "，不在线，请稍后联系"));

        // 2. 获取来源客户
        String fromUserId = sessionService.getUserIdByChannel(ctx.channel());
        UserInfoDTO fromUserInfo = UserInfoCache.getUserInfoByUserId(fromUserId);

        // 3. 构建单聊响应消息
        OneChatResponseCommand oneChatResponseCommand = new OneChatResponseCommand(msg.getMessage(),fromUserInfo.getUserName());
        oneChatResponseCommand.setRetCode(ResponseStatusEnum.SUCCESS.getCode());
        Message message = MessageBuilder.buildMessage(oneChatResponseCommand,fromUserId, toUserInfo.getUserId());

        toUserChannel.writeAndFlush(message);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.attr(AttributeKey.valueOf(Attributes.SERVER_EXCEPTION_RESPONSE_CLASS.getKey()))
                .set(CommandTypeEnum.ONE_CHAT_RESPONSE_COMMAND.getCommandTypeClass());

        ctx.pipeline().get(ServerExceptionHandler.class).exceptionCaught(ctx,cause);
    }
}
